package cz.zcu.sefler.mois.business;

import java.util.ArrayList;
import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.StartTag;
import net.htmlparser.jericho.TextExtractor;
import cz.zcu.sefler.mois.data.model.Monitor;
import cz.zcu.sefler.mois.data.model.Sentence;

/**
 * Tato metoda dedi tridu GeneralMonitorThread. Rozsiruje tak funkcnost
 * zakladniho monitoru, ktery zpracovava rozhovory. Je postaven specificky pro
 * rozhovory ze serveru super.cz.
 * 
 * @author Vojtech Sefler
 * 
 */
public class SuperCzMonitorThread extends GeneralMonitorThread {

  public SuperCzMonitorThread(Monitor monitor, String dbMachine, String dbDb, String dbUser, String dbPass) {
    super(monitor, dbMachine, dbDb, dbUser, dbPass);
  }

  /**
   * Metoda ze stranky vybira pouze text rozhovoru, ostatni (navigace, reklamy,
   * diskuze, atd.) ignoruje.
   */
  @Override
  protected String sourceSegmentToText(Segment source) {

    TextExtractor textExtractor = null;
    List<Element> lst = source.getAllElements();

    /*
     * Projdu vsechny elementy stranky, dokud nenajdu element obsahujici text
     * rozhovoru.
     */
    for (Element element : lst) {
      if ((element.getName() == HTMLElementName.DIV) && (element.getAttributeValue("class") != null)
          && (element.getAttributeValue("class").contains("content"))) {

        /*
         * Vytvorim TextExtractor, ktery ziska z elementu veskery textovy obsah.
         * Definuji tez, jake vnitrni elementy tohoto zdrojoveho prvku se maji
         * vyloucit ze zpracovani.
         */
        textExtractor = new TextExtractor(element) {
          public boolean excludeElement(StartTag startTag) {
            if (startTag.getName() == HTMLElementName.A) {
              /*
               * Odkaz na profil autora nechame, nebot by jmeno chybelo v
               * rozhovoru.
               */
              if ((startTag.getAttributeValue("href") != null) && (startTag.getAttributeValue("href").contains("/celebrity/"))) {
                return false;
              }
              /* Ostatni odkazy vyloucime. */
              return true;
            }

            return false;
          }
        };
      }
    }

    /* Obsah atributu ignorujeme. */
    textExtractor.setIncludeAttributes(false);

    /*
     * Veskere bile znaky lezici bezprostredne vedle sebe budou nahrazeny jednou
     * mezerou.
     */
    textExtractor.setConvertNonBreakingSpaces(true);

    /* Odstraneni nepripustnych znaku - odrazky, sipky, smajlici, atd. */
    return replaceWeirdCharacters(textExtractor.toString());
  }

  /**
   * Metoda dostrani z textu nepripustne znaky a spojeni, ktere nemaji, pro ucel
   * nasi prace, vyznam.
   * 
   * @param text
   *          Text, ze ktereho maji byt odstraneny nepripustne znaky.
   * @return Opraveny text.
   */
  private String replaceWeirdCharacters(String text) {
    /* PUNCTUATION SPACE */
    text = text.replace(Character.toString((char) 8200), " ");

    /* NO-BREAK SPACE */
    text = text.replace(Character.toString((char) 160), " ");

    /* BLACK CIRCLE */
    text = text.replace(Character.toString((char) 9679), "");

    /* SOFT HYPHEN */
    text = text.replace(Character.toString((char) 173), "");

    /* HORIZONTAL ELLIPSIS */
    text = text.replace(Character.toString((char) 8230), "...");

    /* CIRCLED HEAVY WHITE RIGHTWARDS ARROW */
    text = text.replace(Character.toString((char) 10162) + " ", "");

    text = text.replace("* ", "");
    text = text.replace(">>> ", "");
    text = text.replace(">> ", "");
    text = text.replace(">", "");
    text = text.replace("(smích)", "");
    text = text.replace("(směje se) ", "");
    text = text.replace(" (směje se)", "");
    text = text.replace("(rozesměje se) ", "");
    text = text.replace("(Smích) ", "");

    return text;
  }

  /**
   * Tato metoda k funkcnosti prekryte metody predka pridava odstraneni posledni
   * radky, na ktere se nachazi jmeno autora.
   */
  @Override
  protected void textLinesToList(String text, ArrayList<Sentence> list) {

    String[] pole = text.split("\n");
    for (String line : pole) {
      list.add(new Sentence(line, null));
    }

    /* Odstranim jmeno autora */
    list.remove(list.size() - 1);
  }
}
